package yns.springcloud.oakwood.guide.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpStatusCode;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestClient.Builder;

import yns.springcloud.oakwood.guide.bean.User;
import yns.springcloud.oakwood.guide.configure.Configure;
import yns.springcloud.oakwood.guide.errorhandler.RestClientErrorHandler;


@RestController
public class RestClientController {
	
	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private LoadBalancerClient loadBalancerClient;
	
	@Autowired
	@Qualifier("loadBalanced")
	private Builder loadBalancedRestClientBuilder;
	
	@Autowired
	@Qualifier("single")
	private Builder singleRestClientBuilder;
	
	private Configure configure;
	public String applicationName;
	
	@Autowired
	public RestClientController(Configure configure){
		this.applicationName = configure.getProducerName();
		this.configure = configure;
	}
	
	
	@GetMapping("/restClient")
	public String restClient(@RequestParam("value") String value) {
		logger.info("Service Port : " + configure.getPort() + " restClient value : " + value);

		ServiceInstance serviceInstance = loadBalancerClient.choose(applicationName);

		String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/producer?value=" + value;

		logger.info(url);

		RestClient restClient = singleRestClientBuilder.build();
		String response = restClient.get().uri(url)
				.retrieve()
				.onStatus(HttpStatusCode::isError,(httpRequest, httpResponse) -> new RestClientErrorHandler().restClientErrorHandler(value))
				.body(String.class);
		
		logger.info(response);
		
		return response;
	}
	
	@GetMapping("/restClient2")
	public String restClient2(@RequestParam("value") String value) {		
		logger.info("Service Port : " + configure.getPort() + " restClient2 value : " + value);
		
		String url = "http://" + applicationName + "/producer?value=" + value;
		
		logger.info(url);
		
		RestClient restClient = loadBalancedRestClientBuilder.build();
		String response = restClient.get().uri(url)
				.retrieve()
				.onStatus(HttpStatusCode::isError,(httpRequest, httpResponse) -> new RestClientErrorHandler().restClient2ErrorHandler(value))
				.body(String.class);
		
		logger.info(response);
		
		return response;
	}
	
	@GetMapping("/restClient3")
	public String restClient3(@RequestParam("name") String name,@RequestParam("pwd") String pwd) {		
		logger.info("Service Port : " + configure.getPort() + " restClient3 name : " + name + " pwd : " + pwd);
		
		User user = new User();
		user.setName(name);
		user.setPwd(pwd);
		
		String url = "http://" + applicationName + "/producer2";
		
		logger.info(url);
		
		RestClient restClient = loadBalancedRestClientBuilder.build();
		String response = restClient.post().uri(url)
				.body(user)
				.retrieve()
				.onStatus(HttpStatusCode::isError,(httpRequest, httpResponse) -> new RestClientErrorHandler().restClient3ErrorHandler(user))
				.body(String.class);
		
		logger.info(response);
		
		return response;
	}
	
	
	@GetMapping("/restClient4")
	public String restClient4(@RequestParam("name") String name,@RequestParam("pwd") String pwd) {		
		logger.info("Service Port : " + configure.getPort() + " restClient4 name : " + name + " pwd : " + pwd);
		
		User user = new User();
		user.setName(name);
		user.setPwd(pwd);
		
		String url = "http://" + applicationName + "/producer3";
		
		logger.info(url);
		
		RestClient restClient = loadBalancedRestClientBuilder.build();
		String response = restClient.put().uri(url)
				.body(user)
				.retrieve()
				.onStatus(HttpStatusCode::isError,(httpRequest, httpResponse) -> new RestClientErrorHandler().restClient4ErrorHandler(user))
				.body(String.class);
		
		logger.info(response);
		
		return response;
	}	
}
